home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / glue.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  11KB  |  469 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : Aug 1985.
  7.  *
  8.  *    %W%    %G%
  9. */
  10. #include "fig.h"
  11. #include "resources.h"
  12. #include "alloc.h"
  13. #include "func.h"
  14. #include "object.h"
  15. #include "paintop.h"
  16.  
  17. #define            TOLERANCE    7
  18. /*#define            min(a, b)    (((a) < (b)) ? (a) : (b))*/
  19. /*#define            max(a, b)    (((a) > (b)) ? (a) : (b))*/
  20.  
  21. extern F_pos        last_position, new_position;  /* undo.c   */
  22. extern int        fix_x, fix_y, cur_x, cur_y;
  23.  
  24. extern            (*canvas_kbd_proc)();
  25. extern            (*canvas_locmove_proc)();
  26. extern            (*canvas_leftbut_proc)();
  27. extern            (*canvas_middlebut_proc)();
  28. extern            (*canvas_rightbut_proc)();
  29. extern            null_proc();
  30. extern            set_popupmenu();
  31.  
  32. extern F_compound    objects;
  33. extern int        compoundbox_shown;
  34. extern int        pointmarker_shown;
  35. extern int        foreground_color, background_color;
  36.  
  37.             create_compound();
  38. F_compound        *compound_point_search();
  39.  
  40.             init_create_compound();
  41.  
  42. compound_selected()
  43. {
  44.     canvas_kbd_proc = null_proc;
  45.     canvas_locmove_proc = null_proc;
  46.     canvas_leftbut_proc = init_create_compound;
  47.     canvas_middlebut_proc = null_proc;
  48.     canvas_rightbut_proc = set_popupmenu;
  49.     set_cursor(&arrow_cursor);
  50.     reset_action_on();
  51.     }
  52.  
  53. init_create_compound(x, y)
  54. int    x, y;
  55. {
  56.     init_box_drawing(x, y);
  57.     canvas_middlebut_proc = create_compound;
  58.     canvas_leftbut_proc = canvas_rightbut_proc = null_proc;
  59.     }
  60.  
  61. create_compound(x, y)
  62. int    x, y;
  63. {
  64.     F_compound    *c;
  65.  
  66.     if (NULL == (Compound_malloc(c))) {
  67.         put_msg(Err_mem);
  68.         return;
  69.         }
  70.     draw_rectbox(fix_x, fix_y, cur_x, cur_y, INV_PAINT);
  71.     c->nwcorner.x = min(fix_x, x);
  72.     c->nwcorner.y = min(fix_y, y);
  73.     c->secorner.x = max(fix_x, x);
  74.     c->secorner.y = max(fix_y, y);
  75.     if (compose_compound(c) == 0) {
  76.         free((char*)c);
  77.         compound_selected();
  78.         put_msg("Empty compound, ignore");
  79.         return;
  80.         }
  81.     draw_compoundbox(c, INV_PAINT);
  82.     c->next = NULL;
  83.     clean_up();
  84.     set_action(F_GLUE);
  85.     insert_compound(&objects.compounds, c);
  86.     set_latestcompound(c);
  87.     compound_selected();
  88.     }
  89.  
  90. compose_compound(c)
  91. F_compound    *c;
  92. {
  93.     c->ellipses = NULL;
  94.     c->lines = NULL;
  95.     c->texts = NULL;
  96.     c->splines = NULL;
  97.     c->arcs = NULL;
  98.     c->compounds = NULL;
  99.     get_ellipse(&c->ellipses, c->nwcorner.x, c->nwcorner.y,
  100.         c->secorner.x, c->secorner.y);
  101.     get_lineobj(&c->lines, c->nwcorner.x, c->nwcorner.y,
  102.         c->secorner.x, c->secorner.y);
  103.     get_spline(&c->splines, c->nwcorner.x, c->nwcorner.y,
  104.         c->secorner.x, c->secorner.y);
  105.     get_text(&c->texts, c->nwcorner.x, c->nwcorner.y,
  106.         c->secorner.x, c->secorner.y);
  107.     get_arc(&c->arcs, c->nwcorner.x, c->nwcorner.y,
  108.         c->secorner.x, c->secorner.y);
  109.     get_compound(&c->compounds, c->nwcorner.x, c->nwcorner.y,
  110.              c->secorner.x, c->secorner.y);
  111.     /*  get rid of point-marker  */
  112.     if (pointmarker_shown) toggle_compoundpointmarker(c);
  113.     if (c->ellipses != NULL) return(1);
  114.     if (c->splines != NULL) return(1);
  115.     if (c->lines != NULL) return(1);
  116.     if (c->texts != NULL) return(1);
  117.     if (c->arcs != NULL) return(1);
  118.     if (c->compounds != NULL) return(1);
  119.     return(0);
  120.     }
  121.  
  122. draw_compoundbox(c, op)
  123. F_compound    *c;
  124. int        op;
  125. {
  126.     draw_rectbox( c->nwcorner.x-1, c->nwcorner.y-1,
  127.         c->secorner.x+1, c->secorner.y+1, op);
  128.     draw_rectbox( c->nwcorner.x, c->nwcorner.y,
  129.         c->secorner.x, c->secorner.y, op);
  130.     draw_rectbox( c->nwcorner.x+1, c->nwcorner.y+1,
  131.         c->secorner.x-1, c->secorner.y-1, op);
  132.     }
  133.  
  134. get_ellipse(list, xmin, ymin, xmax, ymax)
  135. F_ellipse    **list;
  136. int        xmin, ymin, xmax, ymax;
  137. {
  138.     F_ellipse    *e, *ee, *ellipse;
  139.  
  140.     for (e = objects.ellipses; e != NULL;) {
  141.         if (xmin > e->center.x - e->radiuses.x) { 
  142.         ee = e; e = e->next; continue;
  143.         }
  144.         if (xmax < e->center.x + e->radiuses.x) {
  145.         ee = e; e = e->next; continue;
  146.         }
  147.         if (ymin > e->center.y - e->radiuses.y) {
  148.         ee = e; e = e->next; continue;
  149.         }
  150.         if (ymax < e->center.y + e->radiuses.y) {
  151.         ee = e; e = e->next; continue;
  152.         }
  153.         ellipse = e;
  154.         if (e == objects.ellipses) 
  155.         e = objects.ellipses = objects.ellipses->next;
  156.         else {
  157.         e = ee->next = e->next;
  158.         }
  159.         ellipse->next = *list;
  160.         *list = ellipse;
  161.         }
  162.     }
  163.  
  164. get_arc(list, xmin, ymin, xmax, ymax)
  165. F_arc    **list;
  166. int        xmin, ymin, xmax, ymax;
  167. {
  168.     F_arc    *a, *arc, *aa;
  169.     int    urx, ury, llx, lly;
  170.  
  171.     for (a = objects.arcs; a != NULL;) {
  172.         arc_bound(a, &llx, &lly, &urx, &ury);
  173.         if (xmin > llx) goto out;
  174.         if (xmax < urx) goto out;
  175.         if (ymin > lly) goto out;
  176.         if (ymax < ury) goto out;
  177.         arc = a;
  178.         if (a == objects.arcs) 
  179.         a = objects.arcs = objects.arcs->next;
  180.         else
  181.         a = aa->next = a->next;
  182.         arc->next = *list;
  183.         *list = arc;
  184.         continue;
  185.     out:
  186.         aa = a; a = a->next;
  187.         }
  188.     }
  189.  
  190. get_lineobj(list, xmin, ymin, xmax, ymax)
  191. F_line    **list;
  192. int    xmin, ymin, xmax, ymax;
  193. {
  194.     F_line    *line, *l, *ll;
  195.     F_point    *p;
  196.     int    inbound;
  197.  
  198.     for (l = objects.lines; l != NULL;) {
  199.         for (inbound = 1, p = l->points; p!= NULL && inbound; 
  200.             p = p->next) {
  201.         inbound = 0;
  202.         if (xmin > p->x) continue;
  203.         if (xmax < p->x) continue;
  204.         if (ymin > p->y) continue;
  205.         if (ymax < p->y) continue;
  206.         inbound = 1;
  207.         }
  208.         if (! inbound) {
  209.         ll = l; l = l->next; continue;
  210.         }
  211.         line = l;
  212.         if (l == objects.lines) 
  213.         l = objects.lines = objects.lines->next;
  214.         else
  215.         l = ll->next = l->next;
  216.         line->next = *list;
  217.         *list = line;
  218.         }
  219.     }
  220.  
  221. get_spline(list, xmin, ymin, xmax, ymax)
  222. F_spline    **list;
  223. int        xmin, ymin, xmax, ymax;
  224. {
  225.     F_spline    *spline, *s, *ss;
  226.     int        urx, ury, llx, lly;
  227.  
  228.     for (s = objects.splines; s != NULL;) {
  229.         spline_bound(s, &llx, &lly, &urx, &ury);
  230.         if (xmin > llx) goto out;
  231.         if (xmax < urx) goto out;
  232.         if (ymin > lly) goto out;
  233.         if (ymax < ury) goto out;
  234.         spline = s;
  235.         if (s == objects.splines) 
  236.         s = objects.splines = objects.splines->next;
  237.         else
  238.         s = ss->next = s->next;
  239.         spline->next = *list;
  240.         *list = spline;
  241.         continue;
  242.     out:
  243.         ss = s; s = s->next;
  244.         }
  245.     }
  246.  
  247. get_text(list, xmin, ymin, xmax, ymax)
  248. F_text    **list;
  249. int    xmin, ymin, xmax, ymax;
  250. {
  251.     F_text    *text, *t, *tt;
  252.     for (t = objects.texts; t != NULL;) {
  253.         if (xmin > t->base_x) {
  254.         tt = t; t = t->next; continue;
  255.         }
  256.         if (xmax < t->base_x + t->length) {
  257.         tt = t; t = t->next; continue;
  258.         }
  259.         if (ymin > t->base_y - t->height) {
  260.         tt = t; t = t->next; continue;
  261.         }
  262.         if (ymax < t->base_y) {
  263.         tt = t; t = t->next; continue;
  264.         }
  265.         text = t;
  266.         if (t == objects.texts) 
  267.         t = objects.texts = objects.texts->next;
  268.         else
  269.         t = tt->next = t->next;
  270.         text->next = *list;
  271.         *list = text;
  272.         }
  273.     }
  274.  
  275. get_compound(list, xmin, ymin, xmax, ymax)
  276. F_compound    **list;
  277. int    xmin, ymin, xmax, ymax;
  278. {
  279.     F_compound    *compd, *c, *cc;
  280.     for (c = objects.compounds; c != NULL;)
  281.     {
  282.         if (xmin > c->nwcorner.x)
  283.         {
  284.             cc = c;
  285.             c = c->next;
  286.             continue;
  287.         }
  288.         if (xmax < c->secorner.x)
  289.         {
  290.             cc = c;
  291.             c = c->next;
  292.             continue;
  293.         }
  294.         if (ymin > c->nwcorner.y)
  295.         {
  296.             cc = c;
  297.             c = c->next;
  298.             continue;
  299.         }
  300.         if (ymax < c->secorner.y)
  301.         {
  302.             cc = c;
  303.             c = c->next;
  304.             continue;
  305.         }
  306.         compd = c;
  307.         if (c == objects.compounds) 
  308.             c = objects.compounds = objects.compounds->next;
  309.         else
  310.             c = cc->next = c->next;
  311.         compd->next = *list;
  312.         *list = compd;
  313.     }
  314. }
  315.  
  316. F_compound *
  317. compound_point_search(x, y, tol, px, py)
  318. int    x, y, tol, *px, *py;
  319. {
  320.     F_compound    *c;
  321.  
  322.     for (c = objects.compounds; c != NULL; c = c->next) {
  323.         if (abs(c->nwcorner.x - x) <= tol && 
  324.         abs(c->nwcorner.y - y) <= tol) {
  325.         *px = c->nwcorner.x;
  326.         *py = c->nwcorner.y;
  327.         return(c);
  328.         }
  329.         if (abs(c->nwcorner.x - x) <= tol && 
  330.         abs(c->secorner.y - y) <= tol) {
  331.         *px = c->nwcorner.x;
  332.         *py = c->secorner.y;
  333.         return(c);
  334.         }
  335.         if (abs(c->secorner.x - x) <= tol && 
  336.         abs(c->nwcorner.y - y) <= tol) {
  337.         *px = c->secorner.x;
  338.         *py = c->nwcorner.y;
  339.         return(c);
  340.         }
  341.         if (abs(c->secorner.x - x) <= tol && 
  342.         abs(c->secorner.y - y) <= tol) {
  343.         *px = c->secorner.x;
  344.         *py = c->secorner.y;
  345.         return(c);
  346.         }
  347.         }
  348.     return(NULL);
  349.     }
  350.  
  351. draw_compound(c)
  352. F_compound    *c;
  353. {
  354.     draw_compoundelements(c, foreground_color, foreground_color,
  355.                 PAINT, PAINT, PAINT, PAINT);
  356.     }
  357.  
  358. erase_compound(c)
  359. F_compound    *c;
  360. {
  361.     draw_compoundelements(c, background_color, background_color,
  362.                 ERASE, ERASE, INV_PAINT, ERASE);
  363.     }
  364.  
  365. draw_compoundelements(c, arcop, ellipseop, lineop, splineop, textop, compop)
  366. F_compound    *c;
  367. int        arcop, ellipseop, lineop, splineop, textop, compop;
  368. {
  369.     F_line        *l;
  370.     F_spline    *s;
  371.     F_ellipse    *e;
  372.     F_text        *t;
  373.     F_arc        *a;
  374.     F_compound    *c1;
  375.     
  376.     pw_batch_on(canvas_pixwin);
  377.     for (l = c->lines; l != NULL; l = l->next) {
  378.         draw_line(l, lineop);
  379.         }
  380.     for (s = c->splines; s != NULL; s = s->next) {
  381.         draw_spline(s, splineop);
  382.        } 
  383.     for (a = c->arcs; a != NULL; a = a->next) {
  384.         draw_arc(a, arcop);
  385.        } 
  386.     for (e = c->ellipses; e != NULL; e = e->next) {
  387.         draw_ellipse(e, ellipseop);
  388.         }
  389.     for (t = c->texts; t != NULL; t = t->next) {
  390.         draw_text(t, textop);
  391.         }
  392.     for (c1 = c->compounds; c1 != NULL; c1 = c1->next) {
  393.         draw_compoundbox(c1, INV_PAINT);
  394.         compop == ERASE ? erase_compound(c1) : draw_compound(c1);
  395.         }
  396.     pw_batch_off(canvas_pixwin);
  397.     }
  398.  
  399. F_compound *
  400. compound_search(x, y, tolerance, px, py)
  401. int    x, y, tolerance, *px, *py;
  402. {
  403.     F_compound    *c;
  404.     float        tol2;
  405.  
  406.     tol2 = tolerance * tolerance;
  407.     
  408.     for (c = objects.compounds; c != NULL; c = c->next) {
  409.         if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->nwcorner.x,
  410.             c->secorner.y, x, y, tolerance, tol2, px, py)) 
  411.         return(c);
  412.         if (close_to_vector(c->secorner.x, c->secorner.y, c->nwcorner.x,
  413.             c->secorner.y, x, y, tolerance, tol2, px, py)) 
  414.         return(c);
  415.         if (close_to_vector(c->secorner.x, c->secorner.y, c->secorner.x,
  416.             c->nwcorner.y, x, y, tolerance, tol2, px, py)) 
  417.         return(c);
  418.         if (close_to_vector(c->nwcorner.x, c->nwcorner.y, c->secorner.x,
  419.             c->nwcorner.y, x, y, tolerance, tol2, px, py)) 
  420.         return(c);
  421.         }
  422.     return(NULL);
  423.     }
  424.  
  425. toggle_compoundpointmarker(c)
  426. F_compound    *c;
  427. {
  428.     F_line        *l;
  429.     F_spline    *s;
  430.     F_ellipse    *e;
  431.     F_arc        *a;
  432.  
  433.     for (l = c->lines; l != NULL; l = l->next) {
  434.         toggle_linepointmarker(l);
  435.         }
  436.     for (s = c->splines; s != NULL; s = s->next) {
  437.         toggle_splinepointmarker(s);
  438.        } 
  439.     for (a = c->arcs; a != NULL; a = a->next) {
  440.         toggle_arcpointmarker(a);
  441.        } 
  442.     for (e = c->ellipses; e != NULL; e = e->next) {
  443.         toggle_ellipsepointmarker(e);
  444.         }
  445.     }
  446.  
  447. show_compoundbox()
  448. {
  449.     F_compound    *c;
  450.  
  451.     if (compoundbox_shown) return;
  452.     compoundbox_shown = 1;
  453.     for (c = objects.compounds; c != NULL; c = c->next) 
  454.         draw_compoundbox(c, INV_PAINT);
  455.     }
  456.  
  457. erase_compoundbox()
  458. {
  459.     F_compound    *c;
  460.  
  461.     if (! compoundbox_shown) return;
  462.     compoundbox_shown = 0;
  463.     for (c = objects.compounds; c != NULL; c = c->next) 
  464.         draw_compoundbox(c, INV_PAINT);
  465.     }
  466.  
  467.  
  468.  
  469.